SRAMFile.cc

Go to the documentation of this file.
00001 /*
00002  * hack4u
00003  * Copyright (C) 2004-2006 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of hack4u.
00007  *
00008  * hack4u is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * hack4u is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with hack4u; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021  */
00022 
00023 // $Id: SRAMFile.cc,v 1.6 2006/03/20 01:00:18 technoplaza Exp $
00024 
00025 #ifdef HAVE_CONFIG_H
00026     #include <config.h>
00027 #endif
00028 
00029 #include <fstream>
00030 
00031 #include "model/SaveSlot.hh"
00032 #include "model/SRAMFile.hh"
00033 
00034 using namespace hack4u;
00035 
00036 SRAMFile::SRAMFile(const wxString &filename) throw(InvalidSRAMException) {
00037     std::ifstream in(filename.mb_str(),
00038         std::ios_base::in | std::ios_base::binary);
00039         
00040     if (!in) {
00041         throw InvalidSRAMException(ISE_NOSUCHFILE);
00042     }
00043     
00044     in.read(sram, SRAM_SIZE);
00045     
00046     if (!in.good()) {
00047         in.close();
00048         
00049         throw InvalidSRAMException(ISE_IOERROR);
00050     }
00051     
00052     in.close();
00053     
00054     char *temp = new char[SAVE_SIZE];
00055     
00056     for (int slot = 0; slot < 3; ++slot) {
00057         std::memcpy(temp, (sram + SRAM_OFFSET + (slot * SAVE_SIZE)), SAVE_SIZE);
00058         saveslot[slot] = new SaveSlot(temp);
00059     }
00060     
00061     delete [] temp;
00062     
00063     // if all slots are invalid, the SRAM contains no valid data
00064     verifyChecksum();
00065     
00066     if (!(isValid(0) || isValid(1) || isValid(2))) {
00067         throw InvalidSRAMException(ISE_BADCHECKSUM);
00068     }
00069     
00070     // create backup file
00071     wxString bakfile = filename + wxT(".bak");
00072     std::ofstream out(bakfile.mb_str(),
00073         std::ios_base::out | std::ios_base::binary);
00074         
00075     if (out) {
00076         out.write(sram, SRAM_SIZE);
00077         out.close();
00078     }
00079 }
00080 
00081 SRAMFile::~SRAMFile() {
00082     for (int i = 0; i < 3; ++i) {
00083         delete saveslot[i];
00084     }
00085 }
00086 
00087 bool SRAMFile::isModified() const {
00088     return (saveslot[0]->isModified() ||
00089             saveslot[1]->isModified() ||
00090             saveslot[2]->isModified());
00091 }
00092 
00093 void SRAMFile::save(const wxString &filename) throw(FileIOException) {
00094     if (isModified()) {
00095         for (int slot = 0; slot < 3; ++slot) {
00096             char *nvram = reinterpret_cast<char *>(saveslot[slot]->nvram);
00097             char *ptr = (sram + SRAM_OFFSET + (slot * SAVE_SIZE));
00098         
00099             std::memcpy(ptr, nvram, SAVE_SIZE);
00100             
00101             if (isValid(slot)) {
00102                 for (int i = 0; i < 3; ++i) {
00103                     char *checksum = (sram + SANITY_OFFSET + slot + (i * 3));
00104                     
00105                     if (i == 0) {
00106                         *checksum = nvram[0];
00107                     } else if (i == 1) {
00108                         *checksum = nvram[0] ^ SANITY_XOR1;
00109                     } else {
00110                         *checksum = nvram[0] ^ SANITY_XOR2;
00111                     }
00112                 }
00113             }
00114         }
00115     }
00116     
00117     std::ofstream out(filename.mb_str(),
00118         std::ios_base::out | std::ios_base::binary);
00119         
00120     if (!out) {
00121         throw FileIOException(FIE_CANNOTOPEN);
00122     }
00123     
00124     out.write(sram, SRAM_SIZE);
00125     
00126     if (!out.good()) {
00127         out.close();
00128         throw FileIOException(FIE_IOERROR);
00129     }
00130     
00131     out.close();
00132     
00133     for (int i = 0; i < 3; ++i) {
00134         saveslot[i]->setModified(false);
00135     }
00136 }
00137 
00138 void SRAMFile::verifyChecksum() {
00139     for (int slot = 0; slot < 3; ++slot) {
00140         char byte1 = getSaveSlot(slot)->checksum();
00141         char byte2 = byte1 ^ SANITY_XOR1;
00142         char byte3 = byte1 ^ SANITY_XOR2;
00143         
00144         valid[slot] = ((byte1 == sram[SANITY_OFFSET + slot]) &&
00145                        (byte2 == sram[SANITY_OFFSET + slot + 3]) &&
00146                        (byte3 == sram[SANITY_OFFSET + slot + 6]) &&
00147                        (byte1 == sram[SRAM_OFFSET + (slot * SAVE_SIZE)]));
00148     }
00149 }
00150 

Generated on Sat Feb 24 10:38:50 2007 for hack4u by  doxygen 1.5.1-p1